package com.san.metadata.controller;

import java.util.List;
import java.util.Map;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.san.base.controller.BaseController;
import com.san.common.annotation.Log;
import com.san.common.utils.Constant;
import com.san.common.utils.PageUtils;
import com.san.common.utils.Query;
import com.san.common.utils.R;
import com.san.metadata.domain.DataSourceDO;
import com.san.metadata.domain.TechnicalColumnsDO;
import com.san.metadata.domain.TechnicalTableDO;
import com.san.metadata.service.DataSourceService;
import com.san.metadata.service.TechnicalMetadataService;
import com.san.metadata.vo.TechnicalColumnsVO;

/**
 * 技术元数据业务控制器
 * 
 * @author hulp
 *
 */
@RequestMapping("/md/technical")
@Controller
public class TechnicalMetadataController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(TechnicalMetadataController.class);

	/**
	 * 本功能地址前缀
	 */
	private static final String PREFIX = "metadata/technical";

	@Autowired
	DataSourceService dataSourceService;

	@Autowired
	TechnicalMetadataService technicalMetadataService;

	/**
	 * 技术元数据列表页
	 * 
	 * @param model
	 * @return
	 */

	@RequiresPermissions("md:technical:view")
	@GetMapping("")
	String technical(Model model) {
		return PREFIX + "/view";
	}

	/**
	 * 技术元数据列表接口
	 * 
	 * @param params
	 * @return
	 */
	@GetMapping("/list")
	@ResponseBody
	public PageUtils findListTechnical(@RequestParam Map<String, Object> params) {
		PageUtils pageUtils = null;
		try {
			Query query = new Query(params);
			pageUtils = technicalMetadataService.list(query);
		} catch (Exception e) {
			logger.error("分页获取技术元数据列表出错", e);
		}

		return pageUtils;
	}

	/**
	 * 跳转到手动建表页面
	 * 
	 * @return
	 */
	@GetMapping("/addByHand")
	@Log("新增技术元数据——手动")
	@RequiresPermissions("md:technical:add")
	String addByHand() {
		return PREFIX + "/addByHand";
	}

	/**
	 * 跳转到交换建表页面
	 * 
	 * @return
	 */
	@GetMapping("/addByExchange")
	@Log("新增技术元数据——交换")
	@RequiresPermissions("md:technical:add")
	String addByExchange() {
		return PREFIX + "/addByExchange";
	}

	/**
	 * 保证技术元数据
	 * 
	 * @param technicalTableDO
	 * @return
	 */
	@RequiresPermissions("md:technical:add")
	@Log("保存技术元数据")
	@PostMapping("/save")
	@ResponseBody
	R save(TechnicalTableDO technicalTableDO) {
		technicalTableDO.setCreateUserId(this.getUserId());
		technicalTableDO.setTargetTableName("T_"+technicalTableDO.getTargetTableName());
		try {
			if (technicalMetadataService.save(technicalTableDO) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("保存技术元数据出错", e);
			return R.error();
		}
		return R.error();
	}

	/**
	 * 编辑技术元数据
	 * 
	 * @param model
	 * @param tableId 表ID
	 * @return
	 */
	@Log("编辑技术元数据")
	@RequiresPermissions("md:technical:edit")
	@GetMapping("/edit/{tableId}")
	String edit(Model model, @PathVariable("tableId") Long tableId) {
		TechnicalTableDO tmdo = null;
		try {
			tmdo = technicalMetadataService.getById(tableId);
		} catch (Exception e) {
			logger.error("获取技术元数据出错", e);
		}
		model.addAttribute("technicalMetadata", tmdo);
		return PREFIX + "/edit";
	}

	/**
	 * 更新技术元数据信息
	 * 
	 * @param technicalTableDO
	 * @return
	 */
	@RequiresPermissions("md:technical:edit")
	@Log("更新技术元数据")
	@PostMapping("/doEdit")
	@ResponseBody
	R doEdit(TechnicalTableDO technicalTableDO) {
		technicalTableDO.setUpdateUserId(this.getUserId());
		try {
			if (technicalMetadataService.doEdit(technicalTableDO) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("更新技术元数据出错", e);
			return R.error();
		}
		return R.error();
	}

	/**
	 * 删除技术元数据
	 * 
	 * @param id
	 * @return
	 */
	@RequiresPermissions("md:technical:remove")
	@Log("删除技术元数据")
	@PostMapping("/remove")
	@ResponseBody
	R remove(Long id) {
		try {
			if (technicalMetadataService.remove(id) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("删除技术元数据出错", e);
			return R.error();
		}
		return R.error("删除技术元数据失败");
	}

	/**
	 * 批量删除技术元数据
	 * 
	 * @param ids id的集合
	 * @return
	 */
	@RequiresPermissions("md:technical:batchRemove")
	@Log("批量删除技术元数据")
	@PostMapping("/batchRemove")
	@ResponseBody
	R batchRemove(@RequestParam("ids[]") Long[] ids) {
		int r = 0;
		try {
			r = technicalMetadataService.batchRemove(ids);
		} catch (Exception e) {
			logger.error("批量删除技术元数据出错", e);
			return R.error();
		}
		if (r > 0) {
			return R.ok();
		}
		return R.error("批量删除技术元数据失败");
	}

	/**
	 * 查询数据源下的表
	 * 
	 * @param sourceId 数据源ID
	 * @return
	 */
	@GetMapping("/listSourceTable")
	@Log("查询数据源下的表")
	@ResponseBody
	public PageUtils listSourceTable(@RequestParam Long sourceId) {
		DataSourceDO dataSourceDO = null;
		try {
			dataSourceDO = (DataSourceDO) dataSourceService.getById(sourceId);
		} catch (Exception e) {
			logger.error("获取数据源信息出错", e);
		}
		PageUtils pageUtils = null;
		try {
			pageUtils = technicalMetadataService.listSourceTable(dataSourceDO);
		} catch (Exception e) {
			logger.error("获取数据源下的表信息出错", e);
		}

		return pageUtils;
	}

	/**
	 * 编辑技术元数据表字段
	 * 
	 * @param model
	 * @param tableId 表ID
	 * @return
	 */
	@RequiresPermissions("md:technical:edit")
	@GetMapping("/editColumns/{tableId}")
	String editColumns(Model model, @PathVariable("tableId") Long tableId) {
		model.addAttribute("tableId", tableId);
		TechnicalTableDO technicalTableDO = null;
		try {
			technicalTableDO = technicalMetadataService.getById(tableId);
		} catch (Exception e) {
			logger.error("获取技术元数据信息出错", e);
		}
		model.addAttribute("technicalTableDO", technicalTableDO);
		if (technicalTableDO.getCreateFlag() == Constant.CREATE_FLAG_YES) {
			return PREFIX + "/viewColumns";
		}
		if (technicalTableDO.getImportType() == Constant.IMPORT_TYPE_HAND) {
			return PREFIX + "/editColumnsByHand";
		}
		return PREFIX + "/editColumns";
	}

	/**
	 * 查询数据源表的所有字段
	 * 
	 * @param model
	 * @param tableId 数据源表ID
	 * @return
	 */
	@RequiresPermissions("md:technical:view")
	@GetMapping("/listColumns/{tableId}")
	@Log("查询数据源表的所有字段")
	@ResponseBody
	public PageUtils listColumns(Model model, @PathVariable("tableId") Long tableId) {
		TechnicalTableDO technicalTableDO = null;
		try {
			technicalTableDO = technicalMetadataService.getById(tableId);
		} catch (Exception e) {
			logger.error("获取技术元数据信息出错", e);
		}
		DataSourceDO dataSourceDO = null;
		try {
			dataSourceDO = (DataSourceDO) dataSourceService.getById(technicalTableDO.getSourceId());
		} catch (Exception e) {
			logger.error("获取数据源信息出错", e);
		}

		PageUtils pageUtils = null;
		if (technicalTableDO.getCreateFlag() == Constant.CREATE_FLAG_YES) { // 已建表则查询字段信息表
			try {
				List<TechnicalColumnsDO> list = technicalMetadataService.allTechnicalColumns(tableId);
				pageUtils = new PageUtils(list, list.size());
			} catch (Exception e) {
				logger.error("获取技术元数据字段关系表信息出错", e);
			}
		} else { // 查询源数据表
			try {
				pageUtils = technicalMetadataService.listColumns(dataSourceDO, technicalTableDO);
			} catch (Exception e) {
				logger.error("获取数据源表字段信息出错", e);
			}
		}

		return pageUtils;
	}

	/**
	 * 数据
	 * 
	 * @param tableId                技术元数据表ID
	 * @param TechnicalColumnsVOList 技术元数据字段List
	 * @return
	 */
	@RequiresPermissions("md:technical:add")
	@Log("批量添加技术元数据字段")
	@PostMapping("/batchColumnsAdd/{tableId}")
	@ResponseBody
	@Transactional
	R batchColumnsAdd(@PathVariable("tableId") Long tableId,
			@RequestBody List<TechnicalColumnsVO> TechnicalColumnsVOList) {
		TechnicalTableDO technicalTableDO = null;
		try {
			technicalTableDO = technicalMetadataService.getById(tableId);
		} catch (Exception e) {
			logger.error("获取技术元数据表信息出错", e);
			return R.error();
		}

		for (TechnicalColumnsVO i : TechnicalColumnsVOList) {
			i.setTableId(technicalTableDO.getTableId());
			i.setCreateUserId(this.getUserId());
		}
		DataSourceDO targetDataSourceDO = null; // 目标数据源DO
		try {
			targetDataSourceDO = (DataSourceDO) dataSourceService.getById(technicalTableDO.getTargetSourceId());
		} catch (Exception e) {
			logger.error("获取数据源信息出错", e);
		}
		int sourceType = Constant.SOURCE_TYPE_MYSQL; // 数据源默认Mysql
		DataSourceDO sourceDataSourceDO = null; // 源数据源DO
		if (technicalTableDO.getSourceId() != null) {
			try {
				sourceDataSourceDO = (DataSourceDO) dataSourceService.getById(technicalTableDO.getSourceId());
				sourceType = sourceDataSourceDO.getSourceType(); // 源数据源
			} catch (Exception e) {
				logger.error("获取数据源信息出错", e);
			}
		}

		boolean flag = technicalMetadataService.saveTable(sourceType, tableId, targetDataSourceDO,
				TechnicalColumnsVOList);
		if (flag) {
			return R.ok();
		}
		return R.error();
	}

	/**
	 * 批量更新技术元数据字段
	 * 
	 * @param tableId                技术元数据
	 * @param TechnicalColumnsVOList 技术元数据字段List
	 * @return
	 */
	@RequiresPermissions("md:technical:add")
	@Log("批量更新技术元数据字段")
	@PostMapping("/batchColumnsUpdate/{tableId}")
	@ResponseBody
	@Transactional
	R batchColumnsUpdate(@PathVariable("tableId") Long tableId,
			@RequestBody List<TechnicalColumnsVO> TechnicalColumnsVOList) {
		int r = 0;
		try {
			r = technicalMetadataService.batchColumnsUpdate(TechnicalColumnsVOList);
		} catch (Exception e) {
			logger.error("批量修改技术元数据字段标记失败", e);
			return R.error();
		}
		if (r > 0) {
			return R.ok();
		}

		return R.error("批量修改技术元数据字段标记失败");
	}

}
